package abg.core.service.sys.impl;


import abg.core.common.security.AuthKit;
import abg.core.common.security.AuthUser;
import abg.core.common.util.StringKit;
import abg.core.domain.db.SysRole;
import abg.core.domain.db.SysRoleMenu;
import abg.core.domain.search.Psh;
import abg.core.domain.sys.MSG;
import abg.core.domain.sys.ServiceException;
import abg.core.mapper.SysRoleMapper;
import abg.core.mapper.SysRoleMenuMapper;
import abg.core.service.sys.SysResService;
import abg.core.service.sys.SysRoleService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

import static abg.core.domain.db.table.SysRoleTableDef.SYS_ROLE;

/**
 * 角色实现
 */
@Slf4j
@Service
public class SysRoleServiceImpl implements SysRoleService {
    @Resource
    private SysResService sysResService;

    @Resource
    private SysRoleMapper sysRoleMapper;

    @Resource
    private SysRoleMenuMapper sysRoleMenuMapper;

    @Override
    public Page<SysRole> pageMyRole(SysRole sysRole, Psh psh) {
        AuthUser authUser = AuthKit.mastLogin();
        QueryWrapper wrapper = QueryWrapper.create().select("*").from(SysRole.class)
                .where(SYS_ROLE.NAME.like(sysRole.getName())).orderBy(SYS_ROLE.SORT.asc()).orderBy(SYS_ROLE.CT.desc());

        //返回该用户创建的角色，不包含自身
        if (!authUser.isRoot()) {
            wrapper.and(SYS_ROLE.CI.eq(authUser.getUserId())).and(SYS_ROLE.ID.notIn(authUser.getRoleIds()));
        }

        Page<SysRole> paginate = sysRoleMapper.paginate(psh.getPageNumber(), psh.getPageSize(), wrapper);
        List<SysRole> records = paginate.getRecords();
        //root返回全部
        for (SysRole role : records) {
            QueryWrapper where1 = QueryWrapper.create().select("menu_id").from(SysRoleMenu.class).where("role_id = ?", role.getId());
            List<Object> objects = sysRoleMapper.selectObjectListByQuery(where1);
            role.setMenuIds(objects);
        }
        return paginate;
    }

    @Override
    public boolean insert(SysRole sysRole) {
        AuthUser authUser = AuthKit.mastLogin();
        String name = sysRole.getName();
        String id = sysRole.getId();

        if (StringKit.isBlank(name)) throw new ServiceException(MSG.PARAM_ER);
        if (authUser.isRoot()) if (StringKit.isBlank(id)) throw new ServiceException(MSG.PARAM_ER);


        //已存在名称
        QueryWrapper wrapper = QueryWrapper.create().from(SysRole.class).where(SYS_ROLE.NAME.eq(name));
        SysRole sysRole1 = sysRoleMapper.selectOneByQuery(wrapper);
        if (sysRole1 != null) throw new ServiceException(MSG.NAME_EXISTS);

        //ROOT用户需要已存在ID数据检查
        if (authUser.isRoot()) {
            wrapper = QueryWrapper.create().from(SysRole.class);
            wrapper.and(SYS_ROLE.ID.eq(id)).where(SYS_ROLE.DEL.in("0", "1"));
            sysRole1 = sysRoleMapper.selectOneByQuery(wrapper);
            if (sysRole1 != null) throw new ServiceException(MSG.ID_EXISTS);
        }
        long insert = sysRoleMapper.insertSelective(sysRole);

        //刷新缓存
        sysResService.refreshRoleResCache(sysRole.getId());

        return true;
    }

    @Override
    public boolean delete(String ids) {
        ArrayList<String> split = StringKit.split(ids);

        sysRoleMapper.deleteBatchByIds(split);

        //刷新缓存
        sysResService.refreshRoleResCache(split);

        return true;
    }

    @Override
    public boolean update(SysRole sysRole) {
        QueryWrapper where = QueryWrapper.create().from(SysRole.class).where("name = ?", sysRole.getName()).and("id !=?", sysRole.getId());
        if (sysRoleMapper.selectOneByQuery(where) != null) throw new ServiceException(MSG.NAME_EXISTS);
        sysRoleMapper.update(sysRole);
        //刷新角色资源缓存
        sysResService.refreshRoleResCache(sysRole.getId());
        return true;
    }

    @Override
    public SysRole info(String id) {
        QueryWrapper where = QueryWrapper.create().from(SysRole.class).where("id = ?", id);
        return sysRoleMapper.selectOneByQuery(where);
    }

    //更新库表中，角色关联的菜单
    //刷新角色具备资源缓存
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateRoleMenu(String roleId, String menuIds) {
        QueryWrapper where = QueryWrapper.create().select("id").from(SysRole.class).where("id = ?", roleId);
        if (sysRoleMapper.selectOneByQuery(where) == null) throw new ServiceException(MSG.ROLE_NOT_EXISTS);

        ArrayList<String> menuIdList = StringKit.split(menuIds);
        if (menuIdList.size() == 0) throw new ServiceException(MSG.PARAM_ER);

        //删除
        QueryWrapper delQuery = QueryWrapper.create().where("role_id=?", roleId);
        long count = sysRoleMenuMapper.deleteByQuery(delQuery);

        //插入
        ArrayList<SysRoleMenu> insertList = new ArrayList<>(menuIdList.size());
        for (String menuId : menuIdList) {
            SysRoleMenu lkRoleMenu = new SysRoleMenu();
            lkRoleMenu.setRoleId(roleId);
            lkRoleMenu.setMenuId(menuId);
            insertList.add(lkRoleMenu);
        }
        long insert = sysRoleMenuMapper.insertBatch(insertList);

        //刷新角色具备资源缓存
        sysResService.refreshRoleResCache(roleId);

        return true;
    }

    @Override
    public List<SysRole> allMyRole() {
        AuthUser authUser = AuthKit.mastLogin();
        List<SysRole> sysRoles = sysRoleMapper.selectListByQuery(QueryWrapper.create());

        //root返回全部
        if (authUser.isRoot()) return sysRoles;

        String account = authUser.getAccount();
        List<String> roleIds = authUser.getRoleIds();

        //返回该用户创建的角色，不包含自身
        return sysRoles.stream().filter(e -> e.getCi() != null && account.contains(e.getCi()) && !roleIds.contains(e.getId())).toList();
    }


}
